<template>
  <div class="el-form-item">
    <label v-if="label">{{ label }}</label>
    <slot></slot>
    <p v-if="error" class="error">{{ error }}</p>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { emitter } from '../../emitter'
export default defineComponent({
  name: 'ElFormItem'
})
</script>
<script setup lang="ts">
import Schema from 'async-validator'
import { ref, withDefaults, inject, onMounted } from 'vue'
import { FormItem, key } from './types'
interface Props {
  label?: string
  prop?: string
}
const props = withDefaults(defineProps<Props>(), {
  label: '',
  prop: ''
})
const error = ref<string>('')
const formData = inject(key)
function validate() {
  if (formData?.rules === undefined) {
    return Promise.resolve({ result: true })
  }
  const rules = formData.rules[props.prop]
  const value = formData.model[props.prop]
  const schema = new Schema({ [props.prop]: rules })
  return schema.validate({ [props.prop]: value }, (errors) => {
    if (errors) {
      error.value = errors[0].message || '校验错误'
    } else {
      error.value = ''
    }
  })
}

let o: FormItem = {
  validate
}
onMounted(() => {
  if (props.prop) {
    emitter.on('validate', () => validate())
    emitter.emit('addFormItem', o)
  }
})

defineExpose({
  o
})
</script>

<style lang="scss" scoped>
@import '../../styles/mixin';

@include b(form-item) {
  margin-bottom: 22px;

  label {
    display: inline-block;
    margin-bottom: 5px;
    line-height: 1.2;
  }

  & .el-form-item {
    margin-bottom: 0;
  }
}

.error {
  color: red;
}
</style>
